package org.bjf.utils;

import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * redis 工具类 理论上不允许直接使用RedisTemplate 要求所有暴露方法都要有超时时间，避免不设置超时redis库爆掉
 */
@Component
public class RedisUtil {

  @Autowired
  protected RedisTemplate redisTemplate;


  public void setex(String key, Object value, long timeout) {
    redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
  }

  public <T> T get(String key, Class<T> clz) {
    Object value = redisTemplate.opsForValue().get(key);
    return clz.cast(value);
  }

  public Set<String> keys(String pattern) {
    return redisTemplate.keys(pattern);
  }

  public void delete(String key) {
    redisTemplate.delete(key);
  }

  public boolean exists(final String key) {
    return redisTemplate.hasKey(key);
  }

  public Long increment(String key, long num) {
    return redisTemplate.opsForValue().increment(key, num);
  }

  public Double increment(String key, double num) {
    return redisTemplate.opsForValue().increment(key, num);
  }

  /**
   * ===========================原生接口 exec开头===========================
   */
  public void execSetex(final String key, final String value, final long timeout) {

    redisTemplate.execute(new RedisCallback() {
      @Override
      public Object doInRedis(RedisConnection conn) throws DataAccessException {
        conn.setEx(key.getBytes(), timeout, value.getBytes());
        return 1L;
      }
    });
  }

}
